/**
 * PdfboxUtil.java
 */

package cn.com.thinvent.dispatch.web.utils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.com.thinvent.dispatch.entity.file.contentVo;
import cn.com.thinvent.dispatch.entity.file.filevo;
import cn.com.thinvent.dispatch.service.biz.impl.PdfFileImpl;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.util.PDFTextStripper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author lyy
 */
@CrossOrigin("*")
@ResponseBody
public class PdfboxUtil {

    private static String PDFPATH = "D:\\个人文件\\研究生文件\\118_thinvent\\java_code\\思创解析文本\\思创解析文本\\2107-330803-04-01-609642\\b5bb90df9a7d42a99d66c61aa8944bed\\批复文件.pdf";
    private static String FILEPATH = "D:/临时文件临时文件.doc";
    public static void main(String[] args) throws Exception {
        //1、输入PDF路径，输出PDF文本
//        String content=getPdfContent(PDFPATH);
//        getFileVo(PDFPATH);
//        System.out.println(content);
//        toFile(content,FILEPATH);
        //2、扫描文件夹
//        String folderPath = "D:\\个人文件\\研究生文件\\118_thinvent\\java_code\\思创解析文本\\思创解析文本"; // 文件夹路径
//        File folder = new File(folderPath);
//        // 检查文件夹是否存在
//        if (folder.exists() && folder.isDirectory()) {
//            scanFolder(folder);
//        } else {
//            System.out.println("文件夹不存在或者不是一个有效的文件夹路径！");
//        }
        //3、getHash
//        System.out.println(md5HashCode32(PDFPATH));


        // 存入数据库
        filevo vo = getFileVo(PDFPATH);
        PdfFileImpl p = new PdfFileImpl();
        p.insertPdf(vo);

    }
    public static String md5HashCode32(String filePath) throws FileNotFoundException {
        FileInputStream fis = new FileInputStream(filePath);
        return md5HashCode32(fis);
    }

    public static String md5HashCode32(InputStream fis) {
        try {
            //拿到一个MD5转换器,如果想使用SHA-1或SHA-256，则传入SHA-1,SHA-256
            MessageDigest md = MessageDigest.getInstance("MD5");

            //分多次将一个文件读入，对于大型文件而言，比较推荐这种方式，占用内存比较少。
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length = fis.read(buffer, 0, 1024)) != -1) {
                md.update(buffer, 0, length);
            }
            fis.close();

            //转换并返回包含16个元素字节数组,返回数值范围为-128到127
            byte[] md5Bytes  = md.digest();
            StringBuffer hexValue = new StringBuffer();
            for (int i = 0; i < md5Bytes.length; i++) {
                int val = ((int) md5Bytes[i]) & 0xff;//解释参见最下方
                if (val < 16) {
                    /**
                     * 如果小于16，那么val值的16进制形式必然为一位，
                     * 因为十进制0,1...9,10,11,12,13,14,15 对应的 16进制为 0,1...9,a,b,c,d,e,f;
                     * 此处高位补0。
                     */
                    hexValue.append("0");
                }
                //这里借助了Integer类的方法实现16进制的转换
                hexValue.append(Integer.toHexString(val));
            }
            return hexValue.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
    public static List<String> scanFolder(List<String> strs, File folder) {
            File[] files = folder.listFiles(); // 获取文件夹下的所有文件和文件夹

            // 遍历文件夹下的所有文件和文件夹
            for (File file : files) {
                if (file.isDirectory()) {
                    scanFolder(strs, file); // 递归调用，扫描子文件夹
                } else {
                    System.out.println(file.getAbsolutePath()); // 输出文件路径
                    strs.add(file.getAbsolutePath());
                    System.out.println(strs);
                }
            }
            return strs;
        }
    /**
     * 根据文本解析pdf的内容<br/>
     * @param
     * @return
     * @throws
     */
    public static filevo getFileVo(String filePath) throws Exception {
        String content = getPdfContent(filePath); //TODO
        String os = System.getProperty("os.name").toLowerCase();
        String[] strs = content.split("\r\n");
        // Linux 环境
        if(os.charAt(0) != 'w') strs = content.split("\n");
        filevo vo = new filevo();
        vo.setHash(md5HashCode32(filePath));    // 根据文件路径进行 MD5 哈希计算
        // 原发改文件文件信息
//        if(strs.length > 10)
//        vo.setFileName(strs[1]);
//        else vo.setFileName(filePath.split("\\\\")[filePath.split("\\\\").length-1]);
        vo.setFileName(filePath.split("\\\\")[filePath.split("\\\\").length-1]);
        vo.setFilePath(filePath);
//        if(strs.length > 10)
//        vo.setFileCode(strs[2]);
//        if(strs.length > 10)
//        vo.setProjectCode(strs[strs.length-1].substring(5,strs[strs.length-1].length()));

        vo.setCreateTime(new Date());
        vo.setUpdateTime(new Date());
//        System.out.println(vo.toString());
        return vo;
    }

    /**
     * 获取pdf的内容<br/>
     * @param pdfPath
     * @return
     * @throws Exception
     */
    public static String getPdfContent(String pdfPath) throws Exception {
        boolean sort = false;// 是否排序
        int startPage = 1;// 开始提取页数
        int endPage = Integer.MAX_VALUE;   // 结束提取页数
        String content = null;//暂时存放pdf内容

        InputStream input = null;
        File pdfFile = new File(pdfPath);
        PDDocument document = null;
        try {
            input = new FileInputStream(pdfFile);
            // 加载 pdf 文档
            PDFParser parser = new PDFParser(input);
            parser.parse();
            document = parser.getPDDocument();
            // 获取内容信息
            PDFTextStripper pts = new PDFTextStripper();
            pts.setSortByPosition(sort);
            endPage = document.getNumberOfPages();
            System.out.println("Total Page: " + endPage);
            pts.setStartPage(startPage);
            pts.setEndPage(endPage);
            try {
                content = pts.getText(document);
            }catch(Exception e) {
                throw e;
            }
            System.out.println("Get PDF Content ...");
        }catch(Exception e){
            throw e;
        } finally {
            if (null != input)
                input.close();
            if (null != document)
                document.close();
        }

//        System.out.println("content:"+content);
        return content;
    }
    private static void toFile(String content,String filePath) {
        try {
            File f = new File(filePath);
            if (!f.exists()) {
                f.createNewFile();
            }
            System.out.println("Write PDF Content to txt file ...");
            BufferedWriter output = new BufferedWriter(new FileWriter(f));
            output.write(content);
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String insertPdfs(String path, String tag) throws Exception {
        //批量插入pdf
        //获取路径
        String folderPath = path; // 文件夹路径
        File folder = new File(folderPath);
        List<String> res = new ArrayList<>();
        // 检查文件夹是否存在
        if (folder.exists() && folder.isDirectory()) {
            res = scanFolder(new ArrayList<String>(), folder);
        } else {
            System.out.println("文件夹不存在或者不是一个有效的文件夹路径！");
        }
        System.out.println(res.size());
        System.out.println(res);
        //处理每一个文件的插入

//        int tagId = p.getOrSetTag(tag);
        int tagId = 1;
        for(String pdfPath : res){
            PdfFileImpl p = new PdfFileImpl();
            filevo vo = getFileVo(pdfPath);
            vo.setTagId(String.valueOf(tagId));
            p.insertPdf(vo);
            String contentRes = getPdfContent(pdfPath);

            Long fileid = vo.getId();

            // 存文本信息
            contentVo cvo = new contentVo();
            cvo.setFileId(fileid);
            cvo.setContent(contentRes);
            p.insertPdfContent(cvo);
        }
        return String.valueOf(res.size());
    }
}









